package com.wuyan.web.base.service;

import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.wuyan.web.base.entity.PubAccount;
import com.wuyan.web.base.entity.PubUser;
import com.wuyan.web.base.form.PubAccountForm;
import com.wuyan.web.base.helper.DataEncryptionHelper;
import com.wuyan.web.base.helper.entity.EntityFieldInfo;
import com.wuyan.web.base.helper.rep.RepPageData;
import com.wuyan.web.base.repo.PubAccountRepo;
import com.wuyan.web.base.repo.PubUserRepoExtend;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.wuyan.web.base.config.EntityConfig.DATA_ENCRYPTION;

/**
 * 扩展
 */

@Slf4j
@Primary
@Service
public class PubAccountServiceExtend extends PubAccountService {

    @Autowired
    private PubAccountRepo pubAccountRepo;

    @Autowired
    private PubUserRepoExtend pubUserRepo;

    /**
     * 创建实体
     *
     * @param form 表单
     * @return 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public PubAccount create(PubAccountForm form) throws Exception {
        PubAccount account = super.create(form);
        createUser(account);
        return account;
    }

    /**
     * 创建实体-批量
     * 根据 EntityConfig.ER_BATCH_INSERT_ON_CLEAR判断是否需要执行对应的清除操作
     *
     * @param forms 表单集合
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<PubAccount> creates(List<PubAccountForm> forms) throws Exception {
        List<PubAccount> accounts = super.creates(forms);
        createUser(accounts);
        return accounts;
    }

    /**
     * 删除实体
     *
     * @param id 需要被删除的行ID组
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer delete(Integer[] id) {
        List<PubAccount> all = pubAccountRepo.findAllById(Arrays.asList(id));

        if (all.isEmpty()) {
            return null;
        }

        List<Integer> ids = all.stream()
                .filter(t -> t.getCfgModify() == 1)
                .map(PubAccount::getId)
                .collect(Collectors.toList());

        List<PubUser> pubUsers = pubUserRepo.findAllByUserIdIn(ids);
        pubUserRepo.deleteAll(pubUsers);

        return pubAccountRepo.deleteAll(ids);
    }

    /**
     * 更新实体
     *
     * @param form 表单
     * @param id   实体id
     * @return 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Optional<PubAccount> update(PubAccountForm form, Integer id) throws Exception {
        return pubAccountRepo.findById(id)
                .filter(t -> t.getCfgModify() == 1)
                .map(pubAccount -> {
                    String password = pubAccount.getPassword();
                    BeanUtils.copyProperties(form, pubAccount);
                    pubAccount.setPassword(password);
                    pubAccount.setOperateTime(LocalDateTime.now());
                    return pubAccountRepo.save(pubAccount);
                });
    }

    /**
     * 根据ID更新指定字段的值
     *
     * @param id    ID
     * @param field 字段名
     * @param value 字段值
     * @return long
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public long updateByField(Integer id, String field, String value) throws Exception {
        return super.updateByField(id, field, value);
    }

    /**
     * 获取一个实体对象
     *
     * @param id 实体id
     * @return 实体对象
     */
    @Override
    public Optional<PubAccount> get(Integer id) {
        return super.get(id);
    }

    /**
     * 分页接口
     *
     * @param predicates      查询条件
     * @param orderSpecifiers 排序
     * @param isPage          是否分页
     * @param page            当前页
     * @param limit           每页大小
     * @return 分页结果
     */
    @Override
    public RepPageData<PubAccount> page(List<Predicate> predicates,
                                        List<OrderSpecifier<?>> orderSpecifiers,
                                        Boolean isPage, Integer page, Integer limit) {
        return super.page(predicates, orderSpecifiers, isPage, page, limit);
    }

    /**
     * 创建用户基本信息
     *
     * @param account 用户账户
     */
    @Transactional(rollbackFor = Exception.class)
    protected void createUser(PubAccount account) {
        // 创建用户基本信息
        PubUser user = PubUser.builder()
                .userId(account.getId())
                .build();
        pubUserRepo.save(user);
    }

    /**
     * 批量创建用户基本信息
     *
     * @param accounts 用户账户
     */
    @Transactional(rollbackFor = Exception.class)
    protected void createUser(List<PubAccount> accounts) {
        accounts.forEach(this::createUser);
    }
}